﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinFormSocketServer
{
    public partial class Form1 : Form
    {
        private Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();

        public Form1()
        {
            InitializeComponent();
            //https://www.cnblogs.com/Impulse/articles/9320539.html
            //如果有两个或多个线程操作某一控件的状态，则可能会迫使该控件进入一种不一致状态。
            //还可能出现其他与线程相关的bug,以及不同线程争用控件引起的死锁问题
            //正式环境应该使用委托(Invoke)的方式访问控件
            CheckForIllegalCrossThreadCalls = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var ip = txtIP.Text;

            if (string.IsNullOrEmpty(ip))
            {
                MessageBox.Show("ip不能为空!");
            }

            var port = txtPort.Text;
            if (string.IsNullOrEmpty(port))
            {
                MessageBox.Show("服务端端口不能为空!");
            }

            Socket socketServer = new Socket(SocketType.Stream, ProtocolType.Tcp);
            IPAddress IPAddress = IPAddress.Parse(ip);
            int serverPort = Convert.ToInt32(port);
            IPEndPoint iPEndPoint = new IPEndPoint(IPAddress, serverPort);
            socketServer.Bind(iPEndPoint);
            socketServer.Listen(10);
            button1.Text = "服务已启动";
            this.Text = "服务已启动";
            button1.Enabled = false;
            Task.Run(() =>
            {
                Accept(socketServer);
            });
        }

        private void Accept(Socket socketServer)
        {
            while (true)
            {
                var newSocket = socketServer.Accept();
                txtMsg.Text += $"{newSocket.RemoteEndPoint}上线了\r\n";
                listBox1.Items.Add(newSocket.RemoteEndPoint);
                dicSocket.Add(newSocket.RemoteEndPoint.ToString(), newSocket);
                Task.Run(() =>
                {
                    Receive(newSocket);
                });
            }
        }

        private void Receive(Socket newSocket)
        {
            while (newSocket.Connected)
            {
                byte[] buffer = new byte[1024 * 1024];
                var readLength = newSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                if (readLength == 0)
                {
                    txtMsg.Text += $"{newSocket.RemoteEndPoint}下线了\r\n";
                    listBox1.Items.Remove(newSocket.RemoteEndPoint);
                    dicSocket.Remove(newSocket.RemoteEndPoint.ToString());
                    newSocket.Shutdown(SocketShutdown.Both);
                    newSocket.Close();
                    return;
                }

                var msg = Encoding.UTF8.GetString(buffer, 0, readLength);
                txtMsg.Text += $"{newSocket.RemoteEndPoint}:{msg}\r\n";
            }

        }

        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedItems.Count<=0)
            {
                MessageBox.Show("请选择你要发送消息的客户端!");
                return;
            }

            var msg = txtSendMsg.Text;
            if (string.IsNullOrEmpty(msg))
            {
                MessageBox.Show("发送的消息不能为空！");
                return;
            }

            foreach (var item in listBox1.SelectedItems)
            {
                dicSocket[item.ToString()].Send(Encoding.UTF8.GetBytes(txtSendMsg.Text));
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            foreach (var item in listBox1.SelectedItems)
            {
                dicSocket[item.ToString()].Shutdown(SocketShutdown.Both);
            }
        }
    }
}
